const util = require('util');
const debug = util.debuglog('oil-game:box:dao');
const moment = require('moment');
const Box = require('./boxSchema');
const treasureBox = require('./treasureBoxSchema');
const {
  boxMaxSize,   //待收取宝箱最大数量
} = require('./consts');

// 从mongodb中获取已拥有宝箱
exports.getOwnBoxInfo = function(uid) {
  return new Promise((resolve, reject) => {
    Box.find({uid, chest_type: 0}, {_id: 0}, function (err, data) {
      if (err) return reject(err);
      resolve(data);
    });
  });
}

// 从mongodb中获取待领取宝箱
exports.getWaitOpenBoxInfo = function(uid) {
  debug("用户 %s 获取待领取宝箱", uid);
  return new Promise((resolve, reject) => {
    Box.find({uid, chest_type: 1}, {_id: 0}, function (err, data) {
      if (err){
        debug("用户 %s 获取待领取宝箱异常  %s", uid, JSON.stringify(err));
        return reject(err);
      }
      debug("用户 %s 获取待领取宝箱 %s", uid, JSON.stringify(data));
      resolve(data);
    });
  });
}

// mongo中修改一个宝箱类型为待收取
exports.changeOneOwnBoxToWait = function(uid, boxId){
  //如果有boxId则修改特定的宝箱
  let params = {uid, chest_type: 0};
  if(boxId) params = Object.assign(params, {id: boxId});
  return new Promise((resolve, reject) => {
    //更改宝箱类型
    Box.updateOne(params, {$set: {chest_type: 1, created_at: new Date().valueOf()}}, function(err, data){
      if(err) return reject(err);
      resolve(data);
    });
  });
}

// mongo中修改宝箱类型为待收取
exports.changeOwnBoxToWait = async function(uid, boxId){
  debug("uid = %s boxId = %s mongo中修改宝箱类型为待收取", uid, boxId);
  //2020年7月24日，倒计时结束需要修改的宝箱一次性3个
  //更改宝箱类型
  await exports.changeOneOwnBoxToWait(uid, boxId);
  //已拥有宝箱数量
  let ownOpenBox = await exports.getOwnBoxInfo(uid);
  //待领取有宝箱数量
  let waitOpenBoxInfo = await exports.getWaitOpenBoxInfo(uid);
  //修改剩下的两个
  //修改二次宝箱，加上上次为三次宝箱
  if(ownOpenBox.length >= 2 && waitOpenBoxInfo.length + 2 <= boxMaxSize){
    debug("uid = %s 开始修改宝箱类型", uid);
    await exports.changeOneOwnBoxToWait(uid);
  } 
  if(ownOpenBox.length >= 1 && waitOpenBoxInfo.length + 1 <= boxMaxSize){
    debug("uid = %s 开始修改宝箱类型", uid);
    await exports.changeOneOwnBoxToWait(uid);
  } 
}

// 保存宝箱
exports.saveBoxList = function(uid, boxList){
  debug("用户 %s 保存当前宝箱数据 %s", uid, JSON.stringify(boxList));
  return new Promise((resolve, reject) => {
    //检测宝箱数据是否为空
    if(boxList.length < 1){ 
      debug("用户 %s 保存当前宝箱数据 %s，检测到宝箱数据为空，即将返回", uid, JSON.stringify(boxList));
      return reject({});
    }
    //使用mongoose包装元素
    let boxListMany = boxList.map(item => new Box(item));
    Box.insertMany(boxListMany, function(err, data){
      if(err){
        debug("用户 %s 保存当前宝箱数据 %s \n出错 %s", uid, JSON.stringify(boxList), JSON.stringify(err));
        return reject(err);
      }
      debug("用户 %s 保存当前宝箱数据 %s 成功 %s", uid, JSON.stringify(boxList), JSON.stringify(data));
      resolve(data);
    });
  });
}

//清空当前用户的所有宝箱
exports.delBoxByUid = function(uid){
  debug("用户 %s 清空当前宝箱数据", uid);
  return new Promise((resolve, reject) => {
    Box.deleteMany({ uid }, function(err, data){
      if(err){ 
        debug("用户 %s 清空当前宝箱数据出错 %s", uid, JSON.stringify(err));
        return reject(err);
      }
      debug("用户 %s 清空当前宝箱数据完成 %s", uid, JSON.stringify(data));
      resolve(data);
    });
  });
}

//同步宝箱获取记录
exports.syncGiveBoxLog = function(uid, give_box_log){
  debug("用户 %s 保存宝箱获取记录", uid);
  return new Promise((resolve, reject) => {
    treasureBox.updateOne({uid}, { $push: { give_log: { $each: give_box_log} } }, function(err, data){
      if(err){ 
        debug("用户 %s 保存宝箱获取记录出错 %s", uid, JSON.stringify(err));
        return reject(err);
      }
      debug("用户 %s 保存宝箱获取记录成功 %s", uid, JSON.stringify(data));
      resolve(data);
    });
  });
}

//同步宝箱打开记录
exports.syncOpenBoxLog = function(uid, open_log){
  debug("用户 %s 保存宝箱打开记录", uid);
  return new Promise((resolve, reject) => {
    treasureBox.updateOne({uid}, { $push: { open_log: { $each: open_log} } }, function(err, data){
      if(err){ 
        debug("用户 %s 保存宝箱打开记录出错 %s", uid, JSON.stringify(err));
        return reject(err);
      }
      debug("用户 %s 保存宝箱打开记录成功 %s", uid, JSON.stringify(data));
      resolve(data);
    });
  });
}

//初始化宝箱记录
exports.initBoxInfo = async function(uid){
  return new Promise((resolve, reject) => {
    treasureBox.findOne({uid}, {_id: 1}, (err,data) => {
      if(err){
        debug("uid = %s 查询宝箱数据异常 %s", uid, JSON.stringify(err));
        return reject(err);
      }
      if(!data){    //初始化宝箱记录
        new treasureBox({uid, give_log: [], open_log: []}).save((err, data) => {
          if(err){
            debug("uid = %s 初始化宝箱数据异常 %s", uid, JSON.stringify(err));
            return reject(err);
          }
          debug("uid = %s 初始化宝箱数据成功 %s", uid, JSON.stringify(data));
          resolve(data);
        });
      }else{    //宝箱记录已初始化
        resolve(data);
      }
    });
  });
}

//返回用户当前的石油交易记录，返回[{oil_num}]
exports.getTodayBoxOilNumList = async function(uid){
  //当天日期
  let todayDate = moment().format('YYYY/MM/DD'); 
  //当天开始日期
  let todayDateStart = new Date(todayDate+' 00:00:00');
  //当天结束日期
  let todayDateEnd = new Date(todayDate+' 23:59:59');

  debug("uid = %s todayDate = %s 查询当日从宝箱中开出的石油总量", uid, todayDate);
  return new Promise((resolve, reject) => {
    treasureBox.aggregate([
      {$match: { uid }},
      {$unwind: "$open_log" },
      {$match: {
        "open_log.open_at": {'$gte': todayDateStart, '$lte': todayDateEnd}, 
        "open_log.type": "oil"
      }},
    ]).exec((err,data) => {
      if(err){
        debug("uid = %s 查询当日从宝箱中开出的石油总量异常 %s", uid, JSON.stringify(err));
        return reject(err);
      }
      debug("uid = %s 查询当日石油宝箱数据异常 %s", uid, JSON.stringify(err));
      resolve(data);
    });
  });
}
